package com.ok.event;

import cn.hutool.core.collection.CollUtil;
import com.ok.constant.WsEventEnum;
import com.ok.constant.ThreadPoolConstant;
import com.ok.utils.SpringUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * websocket 事件管理
 */
@Slf4j
public class WsEventManage {
    private WsEventManage() {
    }

    /**
     * 事件Handle集合，key事件code，value：对应的处理类集合
     */
    private static final Map<String, List<WsEvent>> eventMapHandle = new ConcurrentHashMap<>();

    /**
     * * 借助websocket事件，发布产线管理的数据变动处理事件
     */
    private static WsEvent mesPointDataChangeEvent = null;
    private static WsEvent mesPointDataEvent = null;

    public synchronized static void registerMesPointDataChangeListen(WsEvent event) {
        mesPointDataChangeEvent = event;
    }

    /**
     * * 注册生产产线管理事件
     */
    public synchronized static void registerMesPointDataListen(WsEvent event) {
        mesPointDataEvent = event;
    }

    /**
     * 注册事件
     */
    public synchronized static void registerEventListen(WsEvent event) {
        if (event == null) {
            log.error("event不能为空，注册ws事件失败");
            return;
        }
        //2024-12-18 产线数据变化事件的处理
        if (event.getCurrEventEnum().getCode().equals(WsEventEnum.mesPintRDataChange.getCode())) {
            registerMesPointDataChangeListen(event);
            log.info("mesPointDataChangeEvent:{}注册为产线数据变动的处理器", event.getClass());
            return;
        }
        //2024-12-27 产线监测点实时数据
        if (event.getCurrEventEnum().getCode().equals(WsEventEnum.mesPintRData.getCode())) {
            registerMesPointDataListen(event);
            log.info("mesPointDataEvent:{}注册为产线监测点实时数据处理器", event.getClass());
            return;
        }

        List<WsEvent> list;
        if (!eventMapHandle.containsKey(event.getCurrEventEnum().getCode())) {
            list = new ArrayList<>();
        } else {
            list = eventMapHandle.get(event.getCurrEventEnum().getCode());
        }
        list.add(event);
        eventMapHandle.put(event.getCurrEventEnum().getCode(), list);
    }

    /**
     * * 2024-12-18 产线相关业务比如开关机、告警、产量等监测值发生变化时，发送给业务进行处理
     */
    public static void notifyMesDataChangeEvent(String eventCode, String eventParam) {
        if (mesPointDataChangeEvent != null) {
            log.info("收到产线相关的变动通知，发送给：{}", mesPointDataChangeEvent.getClass());
            mesPointDataChangeEvent.eventHandle(null, eventParam);
        }
    }

    /**
     * * mes产线监测点的实时数据通知事件
     */
    public static void notifyMesDataEvent(String eventCode, String eventParam) {
        if (mesPointDataEvent != null) {
            log.info("收到产线相关的实时数据通知，发送给：" + mesPointDataEvent.getClass());
            mesPointDataEvent.eventHandle(null, eventParam);
        }
    }

    /**
     * 通知事件发生
     *
     * @param eventCode     事件code
     * @param ds            socket对象 ,如果为空，则向当前节点所有的连接发送事件通知
     * @param eventParam    事件参数
     */
    public static void notifyWsEvent(String eventCode, DcomWsSocket ds, String eventParam) {
        log.info("广播事件eventCode:,{},eventParam:{}",eventCode,eventParam);
        List<WsEvent> list = eventMapHandle.get(eventCode);
        if (CollUtil.isEmpty(list)) {
            return;
        }
        ThreadPoolExecutor poolExecutor = SpringUtils.getBean(ThreadPoolConstant.wsEventPool);
        list.forEach(event -> {
            if (ds == null) {
                DcomWsSocket.webSocketServerMAP.forEach((k, v) -> {
                    poolExecutor.execute(() -> {
                        try {
                            event.eventHandle(v, eventParam);
                        } catch (Exception e) {
                            log.error("当前ws事件处理异常：", e);
                        }
                    });
                });
            } else {
                poolExecutor.execute(() -> {
                    try {
                        event.eventHandle(ds, eventParam);
                    } catch (Exception e) {
                        log.error("当前ws事件处理异常!：", e);
                    }
                });
            }
        });
    }
}
